package com.qf.service.impl;

import com.qf.constant.CacheConstants;
import com.qf.constant.StrategyConstants;
import com.qf.feign.CacheFeign;
import com.qf.model.StandardSubmit;
import com.qf.service.FilerChainService;
import com.qf.util.PushMsgUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Set;

/**
 * projectName: sms-platform02
 *
 * @author: 元
 * time: 2021/10/18 0018 16:51
 * description:限流策略实现类
 * 5分钟内限制访问
 */
@Slf4j
@Service(value = "limitFiveMinutes")
public class LimitFiveMinuteServiceImpl implements FilerChainService {

    @Autowired
    private CacheFeign cacheFeign;
    @Autowired
    private PushMsgUtil pushMsgUtil;

    @Override
    public boolean strategy(StandardSubmit standardSubmit) {
        log.info("[策略模块-限流策略],开始执行",standardSubmit);
        //1.获取客户ID和目标手机号
        Integer clientID = standardSubmit.getClientID();
        String mobileNumber = standardSubmit.getDestMobile();

        //2.
        String key = CacheConstants.CACHE_PREFIX_SMS_LIMIT + clientID +":"+mobileNumber;
        //3.调用缓存模块,查询近5分钟内发送短信次数'
        long sendTime = new Date().getTime();
        long fiveBefore = sendTime - 1000*60*5;
        Set<Object> sendNumbers = cacheFeign.zRangeByScore(key,fiveBefore,sendTime);
        //5.判断发送条数
        if (sendNumbers != null && sendNumbers.size() >=3){
            log.info("[策略模块-限流策略],5分钟内的限流策略已经执行! sendTime={},fiveBefore={}, sendNumbers={},",standardSubmit,sendNumbers);
            //6.将日志数据发送到日志Topic队列,让ES保存当前数据
            pushMsgUtil.sendLog(standardSubmit, StrategyConstants.STRATEGY_ERROR_LIMIT);
            //7.将StandardReport对象封装,发送到状态报告到Topic队列中,接口模块再给用户推送
            pushMsgUtil.pushReport(standardSubmit,StrategyConstants.STRATEGY_ERROR_LIMIT);
            return false;
        }else {
            //8.若发送短信次数没有超过要求,也需记录日志
            log.info("[策略模块-限流策略],5分钟内的限流策略执行成功！！！sendTime={},fiveBefore={}, sendNumbers={}",standardSubmit,sendNumbers);

            return true;
    }

    }
}
